package com.foxnicweb.app.patent.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foxnicweb.app.domain.patent.UserMapping;
import com.foxnicweb.app.patent.service.IUserMappingService;
import com.github.foxnic.api.error.ErrorDesc;
import com.github.foxnic.api.transter.Result;
import com.github.foxnic.commons.busi.id.IDGenerator;
import com.github.foxnic.commons.collection.CollectorUtil;
import com.github.foxnic.commons.lang.DataParser;
import com.github.foxnic.commons.log.Logger;
import org.github.foxnic.web.constants.enums.dict.EmployeeStatus;
import org.github.foxnic.web.constants.enums.dict.OrgNodeType;
import org.github.foxnic.web.constants.enums.system.UnifiedUserType;
import org.github.foxnic.web.domain.hrm.*;
import org.github.foxnic.web.domain.job.Job;
import org.github.foxnic.web.domain.oauth.Role;
import org.github.foxnic.web.domain.oauth.RoleVO;
import org.github.foxnic.web.domain.oauth.User;
import org.github.foxnic.web.domain.oauth.UserVO;
import org.github.foxnic.web.domain.system.*;
import org.github.foxnic.web.framework.proxy.ProxyContext;
import org.github.foxnic.web.proxy.hrm.EmployeeServiceProxy;
import org.github.foxnic.web.proxy.hrm.OrganizationServiceProxy;
import org.github.foxnic.web.proxy.hrm.PositionServiceProxy;
import org.github.foxnic.web.proxy.oauth.RoleServiceProxy;
import org.github.foxnic.web.proxy.oauth.UserServiceProxy;
import org.github.foxnic.web.proxy.system.BusiRoleMemberServiceProxy;
import org.github.foxnic.web.proxy.system.BusiRoleServiceProxy;
import org.github.foxnic.web.proxy.system.UserTenantServiceProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * 人员、组织等基础数据同步
 * */
@Component
public class BasicDataSyncExecutor extends BaseJobExecutor {

    /**
     * 是否同步业务角色
     * */
    private final boolean isSyncBusiRole=false;
    @Autowired
    private IUserMappingService userMappingService;

    @Override
    public String getName() {
        return "组织同步";
    }

    @Override
    public Result execute(Object context, Job job, JSONObject methodParams) {
        // 设置调用登录账户
        ProxyContext.setCallerAccount(CALLER_ACCOUNT);
        this.initIf();

        // 同步组织数据
        try {
            this.syncOrganizations();
        } catch (Exception e) {
            Logger.exception(e);
            return ErrorDesc.exception(e);
        }

        //  同步账户数据
        try {
            this.syncUsers();
        } catch (Exception e) {
            Logger.exception(e);
            return ErrorDesc.exception(e);
        }

        //  同步账户数据
        try {
            this.syncRoles();
        } catch (Exception e) {
            Logger.exception(e);
            return ErrorDesc.exception(e);
        }

        return ErrorDesc.success();
    }


    /**
     * 同步组织数据
     * */
    private void syncRoles() {
        Map<String,String> params=new HashMap<>();
        JSONObject data=this.get("/roles",params,"data");
        JSONArray array=data.getJSONArray("data");
        for (int i = 0; i < array.size(); i++) {
            JSONObject itm=array.getJSONObject(i);
            String id=itm.getString("id");

            JSONObject empData=this.get("users?page=1&listRows=2000&query[]=%7B%22operation%22:1,%22roles%22:"+id+"%7D&usertype=1",new HashMap<>(),"data");
            JSONArray emps=empData.getJSONArray("data");
            // 功能角色
            Result<Role> result1= RoleServiceProxy.api().getById(id);
            Role sysRole=null;
            if(result1.failure() || result1.data()==null) {
                // 创建角色
                sysRole=new Role();
                sysRole.setId(id);
                sysRole.setCode(id);
                sysRole.setName(itm.getString("name"));
                RoleServiceProxy.api().insert(RoleVO.createFrom(sysRole));
            } else {
                // 更新角色
                sysRole=result1.data();
                sysRole.setName(itm.getString("name"));
                RoleServiceProxy.api().update(sysRole.toPojo(RoleVO.class));
            }
            for (int j = 0; j < emps.size(); j++) {
                JSONObject empJson=emps.getJSONObject(j);
                //String empId=empJson.getString("id");


                UserVO userVO=new UserVO();
                userVO.setAccount(empJson.getString("user_name"));


                List<User> users= UserServiceProxy.api().queryList(userVO).data();
                if(users==null || users.isEmpty()) {
                    continue;
                }
                String userId=users.get(0).getId();


                // 建立关系
                Result<User> userResult = UserServiceProxy.api().getById(userId);
                if(userResult.failure()) {
                    continue;
                }
                UserVO user= userResult.data().toPojo(UserVO.class);
                Set<String> roleIds= CollectorUtil.collectSet(user.getRoles(),Role::getId);
                roleIds.add(id);
                user.setRoleIds(new ArrayList<>(roleIds));
                UserServiceProxy.api().update(user);
            }


            // 业务角色
            if(isSyncBusiRole) {
                Result<BusiRole> result2 = BusiRoleServiceProxy.api().getById(id);
                BusiRole busiRole = null;
                if (result2.failure() || result2.data() == null) {
                    // 创建角色
                    busiRole = new BusiRole();
                    busiRole.setId(id);
                    busiRole.setCode(id);
                    busiRole.setName(itm.getString("name"));
                    BusiRoleServiceProxy.api().insert(BusiRoleVO.createFrom(busiRole));
                } else {
                    // 更新角色
                    busiRole = result2.data();
                    busiRole.setName(itm.getString("name"));
                    BusiRoleServiceProxy.api().update(BusiRoleVO.createFrom(busiRole));
                }
                for (int j = 0; j < emps.size(); j++) {
                    JSONObject userJson = emps.getJSONObject(j);
                    String empId = userJson.getString("id");
                    // 建立关系
                    BusiRoleMemberVO sample = new BusiRoleMemberVO();
                    sample.setRoleId(id);
                    sample.setMemberId(empId);
                    sample.setMemberType(UnifiedUserType.employee.code());
                    Result<List<BusiRoleMember>> result3 = BusiRoleMemberServiceProxy.api().queryList(sample);
                    if (result3.failure() || result3.data() == null) {
                        continue;
                    }
                    List<BusiRoleMember> memberList = result3.data();
                    if (memberList.isEmpty()) {
                        BusiRoleMemberServiceProxy.api().insert(sample);
                    }
                }
            }




        }
    }


    /**
     * 同步组织数据
     * */
    private void syncOrganizations() {
        Map<String,String> params=new HashMap<>();
        JSONObject data=this.get("/organization_units",params,"data");
        JSONArray array=data.getJSONArray("data");
        for (int i = 0; i < array.size(); i++) {
            JSONObject itm=array.getJSONObject(i);
            OrganizationVO org=new OrganizationVO();
            org.setId(itm.getString("id"));
            org.setCode(itm.getString("id"));
            org.setParentId(itm.getString("parent_id"));
            org.setShortName(itm.getString("name"));
            org.setFullName(itm.getString("name"));
            org.setCompanyId(this.companyId);
            org.setType(OrgNodeType.DEPT.code());
            OrganizationServiceProxy.api().save(org);
        }
    }

    /**
     * 同步账户数据
     * */
    private Result syncUsers() {
        Map<String,String> params=new HashMap<>();
        params.put("listRows","2000");
        JSONObject data=this.get("/users",params,"data");
        JSONArray array=data.getJSONArray("data");

        for (int i = 0; i < array.size(); i++) {
            System.err.println("\n\n== "+i+"/"+array.size()+" ================\n\n");
            JSONObject user=array.getJSONObject(i);
            JSONObject detail=this.get("/users/"+user.getString("id"),new HashMap<>(),"data");
            this.syncUser(user,detail.getJSONObject("user"));
        }
        return ErrorDesc.success();
    }

    private Result syncUser(JSONObject user,JSONObject detail) {

        String empNo=user.getString("id");
        String realName=user.getString("name");
        String account=user.getString("user_name");
        String phoneNumber=user.getString("phone_number");
        // 存在重复，按此处理
        phoneNumber=empNo;
        Boolean isActive=user.getBoolean("is_active");
        Boolean isAdmin=detail.getBoolean("is_admin");
        Integer userType=user.getInteger("usertype");

        if("admin".equals(account)) {
            return ErrorDesc.success().message("admin 账户不用同步");
        }


        // 创建组织
        Organization directOrganization = null;
        Result<Organization> organizationResult=makeOrganizations(detail);
        if(organizationResult.success()) {
            directOrganization=organizationResult.data();
        } else {
            return organizationResult;
        }

        // 创建岗位
        Position position = null;
        Result<Position> positionResult=makeDefaultPosition(directOrganization);
        if(positionResult.success()) {
            position = positionResult.data();
        } else {
            return positionResult;
        }

        // 创建员工
        Result<Employee> employeeResult=makeEmployee(empNo,empNo,userType,account,realName,phoneNumber,position,isActive);
        if(employeeResult.failure()) {
            return employeeResult;
        }

        Result roleResult=makeRoles(detail,account,phoneNumber,isAdmin);
        return roleResult;
    }

    /**
     * 创建员工与账户
     * */
    private Result<Employee> makeEmployee(String empId, String empNo,Integer type,String account,String realName,String phoneNumber,Position position,Boolean isActive) {

        EmployeeVO employee = new EmployeeVO();

        employee.setBadge(empNo);

        EmployeeStatus status=EmployeeStatus.ACTIVE;
        if(!isActive) {
            status=EmployeeStatus.LEAVE;
        }

        Result<List<Employee>> employeeListResult= EmployeeServiceProxy.api().queryList(employee);
        if(employeeListResult.failure()) return new Result<>(employeeListResult);

        if(employeeListResult.data().isEmpty()) {
            employee.setId(empId);
            employee.setPhone(phoneNumber);
            employee.setBadge(empNo);
            employee.setName(realName);
            employee.setPrimaryPositionId(position.getId());
            employee.setIdentity("no:"+ IDGenerator.getNanoId(16));
            employee.setTenantId(tenantId);
            employee.setType(type+"");
            employee.setStatus(status.code());
            employee.setCompanyId(companyId);
            Result result= EmployeeServiceProxy.api().insert(employee);

            if(result.success()) {
                UserVO userVO=new UserVO();
                userVO.setAccount(employee.getBadge());
                List<User> users= UserServiceProxy.api().queryList(userVO).data();
                User user=users.get(0);
                user.setAccount(account);
                user.setPasswd(null);
                UserServiceProxy.api().update(UserVO.createFrom(user));

                // 建立账户映射
                UserMapping mapping=new UserMapping();
                mapping.setLocalUserId(user.getId());
                mapping.setRemoteUserId(DataParser.parseLong(empId));
                mapping.setSyncTime(new Date());
                userMappingService.insert(mapping);

            }



            return result;

        } else {
            Result<Employee> result=new Result<>();
            Employee emp=employeeListResult.data().get(0);
            emp.setName(realName);
            emp.setStatus(status.code());
            emp.setPrimaryPositionId(position.getId());
            emp.setType(type+"");
            EmployeeVO vo=EmployeeVO.createFrom(emp);
            EmployeeServiceProxy.api().update(vo);
            UserTenantVO userTenantVO=new UserTenantVO();
            userTenantVO.setOwnerTenantId(tenantId);
            userTenantVO.setEmployeeId(emp.getId());
            Result<List<UserTenant>> utResult= UserTenantServiceProxy.api().queryList(userTenantVO);
            if(utResult.success()) {
                for (UserTenant ut : utResult.data()) {
                    Result<User> userResult= UserServiceProxy.api().getById(ut.getUserId());
                    if(utResult.success()) {
                        User user=userResult.data();
                        user.setRealName(realName);
                        UserServiceProxy.api().update(UserVO.createFrom(user));
                    }
                }
            }
            return result.success(true).data(emp);
        }




    }

    /**
     * 创建默认岗位
     * */
    private Result<Position> makeDefaultPosition(Organization directOrganization) {
        PositionVO positionVO=new PositionVO();
        positionVO.setOrgId(directOrganization.getId());
        positionVO.setFullName("职员");
        positionVO.setShortName("职员");
        positionVO.setTenantId(tenantId);
        positionVO.setCompanyId(companyId);

        Result<List<Position>> positionListResult = PositionServiceProxy.api().queryList(positionVO);
        if(positionListResult.failure()) return new Result<>(positionListResult);
        else {
            if(positionListResult.data().isEmpty()) {
                Result r=PositionServiceProxy.api().insert(positionVO);
                if(r.failure()) return r;
                positionListResult = PositionServiceProxy.api().queryList(positionVO);
                if(positionListResult.failure()) {
                    return new Result<>(positionListResult);
                } else {
                    if(positionListResult.data().isEmpty()) {
                        throw new RuntimeException("岗位创建失败");
                    } else {
                        Result<Position> result = new Result();
                        return result.success(true).data(positionListResult.data().get(0));
                    }
                }
            } else {
                Result<Position> result=new Result();
                return result.success(true).data(positionListResult.data().get(0));
            }
        }

    }

    /**
     * 返回默认组织节点
     * */
    private  Result<Organization> makeOrganizations(JSONObject detail) {
        JSONArray units=detail.getJSONArray("organization_units");
        if(units==null || units.isEmpty()) {
            return ErrorDesc.failureMessage("账户没有归属组织");
        }
        JSONObject unit=units.getJSONObject(0);
        String id=unit.getString("id");
        return OrganizationServiceProxy.api().getById(id);
    }

    /**
     * 角色赋予
     * */
    private  Result makeRoles(JSONObject detail,String account,String phoneNumber,Boolean isAdmin) {
        JSONObject roles=detail.getJSONObject("roles");
        if(roles==null || roles.isEmpty()) {
            return ErrorDesc.failureMessage("账户没有归属角色");
        }
        String empId=detail.getString("id");
        UserVO userVO=new UserVO();
        userVO.setAccount(account);

        List<User> users= UserServiceProxy.api().queryList(userVO).data();
        String userId=users.get(0).getId();
        for (String id : roles.keySet()) {
             // 功能角色
             Result<Role> result1= RoleServiceProxy.api().getById(id);
             Role sysRole=null;
             if(result1.failure() || result1.data()==null) {
                 // 创建角色
                 sysRole=new Role();
                 sysRole.setId(id);
                 sysRole.setCode(id);
                 sysRole.setName(roles.getString(id));
                 RoleServiceProxy.api().insert(RoleVO.createFrom(sysRole));
             } else {
                 // 更新角色
                 sysRole=result1.data();
                 sysRole.setName(roles.getString(id));
                 RoleServiceProxy.api().update(sysRole.toPojo(RoleVO.class));
             }
             // 建立关系
            Result<User> userResult = UserServiceProxy.api().getById(userId);
            if(userResult.failure()) return userResult;
            UserVO user= userResult.data().toPojo(UserVO.class);
            Set<String> roleIds= CollectorUtil.collectSet(user.getRoles(),Role::getId);
            roleIds.add(id);
            roleIds.add("617103797986000896"); //系统基础通用角色
            roleIds.add("617293164289458176"); //BPM流程使用角色
            roleIds.add("586968144602464256"); //BPM流程基础角色
            if(isAdmin) {
                roleIds.add("582502063569637376"); //BPM流程管理员
                roleIds.add("110352963290923110"); //超级管理员
            }
            user.setRoleIds(new ArrayList<>(roleIds));
            UserServiceProxy.api().update(user);

            // 业务角色
            if(isSyncBusiRole) {
                Result<BusiRole> result2 = BusiRoleServiceProxy.api().getById(id);
                BusiRole busiRole = null;
                if (result2.failure() || result2.data() == null) {
                    // 创建角色
                    busiRole = new BusiRole();
                    busiRole.setId(id);
                    busiRole.setCode(id);
                    busiRole.setName(roles.getString(id));
                    BusiRoleServiceProxy.api().insert(BusiRoleVO.createFrom(busiRole));
                } else {
                    // 更新角色
                    busiRole = result2.data();
                    busiRole.setName(roles.getString(id));
                    BusiRoleServiceProxy.api().update(BusiRoleVO.createFrom(busiRole));
                }
                // 建立关系
                BusiRoleMemberVO sample = new BusiRoleMemberVO();
                sample.setRoleId(id);
                sample.setMemberId(empId);
                sample.setMemberType(UnifiedUserType.employee.code());
                Result<List<BusiRoleMember>> result3 = BusiRoleMemberServiceProxy.api().queryList(sample);
                if (result3.failure() || result3.data() == null) {
                    return result3;
                }
                List<BusiRoleMember> memberList = result3.data();
                if (memberList.isEmpty()) {
                    BusiRoleMemberServiceProxy.api().insert(sample);
                }
            }


        }

        return ErrorDesc.success();

    }

}
